/**
 * 
 */
package com.probiz.estore.common.service.impl;

import java.math.BigDecimal;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;

import com.probiz.estore.Constants;
import com.probiz.estore.common.model.order.OrderPayment;
import com.probiz.estore.common.model.order.SalesOrder;
import com.probiz.estore.common.model.system.PaymentGateway;
import com.probiz.estore.common.model.system.PaymentHistory;
import com.probiz.estore.common.model.system.PaymentMethod;
import com.probiz.estore.common.service.OrderService;
import com.probiz.estore.common.util.NumberUtil;
import com.probiz.estore.order.OrderConstants;
import com.probiz.estore.order.model.OnlinePaymentResponse;
import com.probiz.estore.order.service.OrderAuditHelper;
import com.probiz.estore.order.service.OrderPaymentManager;
import com.probiz.estore.order.service.SalesOrderManager;
import com.probiz.estore.order.util.OrderCodeGenerator;
import com.probiz.estore.system.service.PaymentHistoryManager;
import com.probiz.estore.system.service.PaymentMethodManager;
import com.probiz.estore.webapp.util.RequestUtil;

public class OrderServiceImpl implements OrderService {

	protected final transient Log logger = LogFactory.getLog(getClass());

	private SalesOrderManager salesOrderManager;

	private OrderPaymentManager orderPaymentManager;
	
	private OrderAuditHelper orderAuditHelper;
	
	private PaymentMethodManager paymentMethodManager;
	
	private PaymentHistoryManager paymentHistoryManager;

	public void setSalesOrderManager(SalesOrderManager salesOrderManager) {
		this.salesOrderManager = salesOrderManager;
	}

	public void setOrderPaymentManager(OrderPaymentManager orderPaymentManager) {
		this.orderPaymentManager = orderPaymentManager;
	}
	

	public void setOrderAuditHelper(OrderAuditHelper orderAuditHelper) {
		this.orderAuditHelper = orderAuditHelper;
	}
	
	

	public void setPaymentMethodManager(PaymentMethodManager paymentMethodManager) {
		this.paymentMethodManager = paymentMethodManager;
	}
	
	

	public void setPaymentHistoryManager(PaymentHistoryManager paymentHistoryManager) {
		this.paymentHistoryManager = paymentHistoryManager;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.common.service.OrderService#getSalesOrderByOrderNo4Safety(java.lang.String,
	 *      java.lang.Integer)
	 */
	public SalesOrder getSalesOrderByOrderNo4Safety(String orderNo, Integer customerId) {
		SalesOrder salesOrder = salesOrderManager.getSalesOrderByOrderNo(orderNo);
		if (salesOrder != null && customerId != null && customerId.equals(salesOrder.getCustomerId())) {
			return salesOrder;
		} else {
			return null;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.common.service.OrderService#getProductCircsInSalesOrder(java.lang.Integer)
	 */
	public short getProductCircsInSalesOrder(Integer productId) {
		if (salesOrderManager.countOrderTotalByProductIdByOrderStatuses(productId, null) == 0) {
			return 2;
		} else if (salesOrderManager.countOrderTotalByProductIdByOrderStatuses(productId, new Short[] { OrderConstants.ORDER_STATUS_AWAITING_CONFIRMATION, OrderConstants.ORDER_STATUS_CONFIRMED,
				OrderConstants.ORDER_STATUS_HANDLING }) >= 1) {
			return 1;
		} else {
			return 0;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.common.service.OrderService#getProductSkuCircsInSalesOrder(java.lang.Integer)
	 */
	public short getProductSkuCircsInSalesOrder(Integer productSkuId) {
		if (salesOrderManager.countOrderTotalByProductSkuIdByOrderStatuses(productSkuId, null) == 0) {
			return 2;
		} else if (salesOrderManager.countOrderTotalByProductSkuIdByOrderStatuses(productSkuId, new Short[] { OrderConstants.ORDER_STATUS_AWAITING_CONFIRMATION, OrderConstants.ORDER_STATUS_CONFIRMED,
				OrderConstants.ORDER_STATUS_HANDLING }) >= 1) {
			return 1;
		} else {
			return 0;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.common.service.OrderService#isCustomerOrderNumZero(java.lang.Integer)
	 */
	public boolean isCustomerOrderNumZero(Integer customerId) {
		long num = salesOrderManager.countCustomerOrder(customerId);
		return num == 0 ? true : false;
	}

	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.common.service.OrderService#doPayOrder4Online(java.lang.String, java.math.BigDecimal, com.probiz.estore.common.model.system.PaymentGateway, java.lang.String, java.lang.String)
	 */
	public void doPayOrder4Online(String orderNo, BigDecimal paymentAmount, PaymentGateway paymentGateway, String payer, String ipAddress){
		SalesOrder salesOrder = salesOrderManager.getSalesOrderByOrderNo(orderNo);
		if(null == salesOrder){
			logger.error("#PayOnLine: create orderPayment(pay online) failed! orderNo=" + orderNo);
			return;
		}
		if (NumberUtil.isZero(salesOrder.getUnPaidAmount())) {
			//如果已经全额支付 则不能进行支付
			logger.error("#PayOnLine: order is paid totally! cannot accept pay again, please check. orderNo=" + orderNo);
		}
		
		OrderPayment orderPayment = new OrderPayment();
		// ----------------收款单号----------------
		boolean isPaymentNoAvailable = false;
		do {
			String payNo = OrderCodeGenerator.generateOrderPaymentNo4Pay();
			Long size = orderPaymentManager.getSizeByDocumentNo(payNo);
			if (size == 0) {
				// 该编码可用
				isPaymentNoAvailable = true;
				orderPayment.setDocumentNo(payNo);
			}
		} while (!isPaymentNoAvailable);
		// ----------------收款单主体----------------
		PaymentMethod paymentMethod = paymentMethodManager.getByPaymentGatewayId(paymentGateway.getPaymentGatewayId());
		if(paymentMethod!=null){
			orderPayment.setPaymentMethodId(paymentMethod.getPaymentMethodId());
			orderPayment.setPaymentTypeDesc(OrderConstants.PAYMENT_METHOD_ONLINE_DESC+" "+paymentMethod.getPaymentMethodName());
		}else{
			orderPayment.setPaymentTypeDesc(OrderConstants.PAYMENT_METHOD_ONLINE_DESC+" "+paymentGateway.getPaymentGatewayName());
		}
		orderPayment.setPaymentGatewayName(paymentGateway.getPaymentGatewayName());
		orderPayment.setPaymentAmount(paymentAmount);
		orderPayment.setPayer(payer);
		orderPayment.setDocumentType(OrderPayment.DOCUMENT_TYPE_PAY);
		orderPayment.setSalesOrder(salesOrder);
		orderPayment.setHasInvoice(salesOrder.getHasInvoice());
		orderPayment.setInvoiceTitle(salesOrder.getInvoiceTitle());
		orderPayment.setIpAddress(ipAddress);
		orderPayment.setPayTime(new Date());
		orderPaymentManager.save(orderPayment);
		// ----------------订单主体----------------
		salesOrder.setPaidAmount(salesOrder.getPaidAmount().add(orderPayment.getPaymentAmount()));
		if (NumberUtil.isZero(salesOrder.getUnPaidAmount())) {
			salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_ALL_PAID);
		} else {
			salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_PARTIALLY_PAID);
		}
		salesOrderManager.save(salesOrder);
		// ----------------订单日志----------------
		orderAuditHelper.doLogPayOrder(salesOrder, orderPayment);

	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.common.service.OrderService#doHandleOnlinePaymentResponse(com.probiz.estore.order.model.OnlinePaymentResponse)
	 */
	public void doHandleOnlinePaymentResponse(OnlinePaymentResponse response,HttpServletRequest request){
		Assert.hasText(response.getOrderNo(), "online payment orderNo cannot be null");
		PaymentHistory paymentHistory=new PaymentHistory();
		paymentHistory.setOrderNo(response.getOrderNo());
		paymentHistory.setPaymentGatewayId(response.getPaymentGateway().getPaymentGatewayId());
		paymentHistory.setAmount(response.getAmount());
		paymentHistory.setFlowNo(response.getFlowNo());
		paymentHistory.setReceiveData(RequestUtil.getRequestMap(request).toString());
		paymentHistory.setRemoteIp(RequestUtil.getRemoteIP(request));
		paymentHistory.setFlag(response.getFlag());
		paymentHistory.setCreateTime(new Date());
		//检查当前的收到的数据是否已经存在于支付历史表里,防止多次收到同一次的支付数据
		//通过流水号+订单号码＋网关+标志进行检查【由于允许多次支付，所以订单号码已经很难作为判断的标准，最好能根据支付网关的流水号】
		boolean isRepeate=paymentHistoryManager.getIsExistPaymentHistory(paymentHistory.getFlowNo(),paymentHistory.getOrderNo(),
				paymentHistory.getPaymentGatewayId(),paymentHistory.getAmount(),paymentHistory.getFlag()); 
		
		if(Constants.PAYMENT_HISTORY_FLAG_SUCCESS.equals(response.getFlag()) && !isRepeate){
			//成功支付且不是支付网关重复发送的记录
		   this.doPayOrder4Online(response.getOrderNo(),response.getAmount(),response.getPaymentGateway(),response.getPayer(),RequestUtil.getRemoteIP(request));
		}else if(Constants.PAYMENT_HISTORY_FLAG_WAIT.equals(response.getFlag())){
			paymentHistory.setErrorMessage("Transaction has commit! but the money has not yet transfer to merchant account, please wait.");
		}else{
			paymentHistory.setErrorMessage(response.getErrorMessage());
		}
		
		paymentHistory.setIsBrowsed(isRepeate?PaymentHistory.BROWSED:PaymentHistory.UNBROWSED);
		paymentHistoryManager.save(paymentHistory);
		
	}
	
	public short getGiftCircsInSalesOrder(Integer giftId) {
		if (salesOrderManager.countOrderTotalByGiftIdByOrderStatuses(giftId, null) == 0) {
			return 2;
		} else if (salesOrderManager.countOrderTotalByGiftIdByOrderStatuses(giftId, new Short[] { OrderConstants.ORDER_STATUS_AWAITING_CONFIRMATION, OrderConstants.ORDER_STATUS_CONFIRMED,
				OrderConstants.ORDER_STATUS_HANDLING }) >= 1) {
			return 1;
		} else {
			return 0;
		}
	}

}
